package com.jwdemo
{
	//import org.flexunit.Assert;
	
	public class Vector4
	{
		private var _x:Number	=	0.0 ;
		private var _y:Number	=	0.0 ;
		private var _z:Number	=	0.0 ;
		private var _w:Number	=	0.0 ;
		
//		public function Vector4()
//		{
//		}

		public function Vector4(x:Number,y:Number,z:Number = 0.0, w:Number = 0)
		{
			this._x	=	x ;
			this._y	=	y ;
			this._z	=	z ;
			this._w	=	w ;
		}


//		public function Vector4(vec:Vector4)
//		{
//			this._x	=	vec.X() ;
//			this._y	=	vec.Y() ;
//			this._z	=	vec.Z() ;
//			this._w	=	vec.W() ;
//		}
		
		public function X():Number
		{
			return _x ;
		}

		public function Y():Number
		{
			return _y ;
		}

		public function Z():Number
		{
			return _z ;
		}

		public function W():Number
		{
			return _w ;
		}
		
		public function SetBroadcast(val:Number = 0.0):void
		{
			this.SetXyzw(val,val,val,val) ;
		}

		public function SetXyzw(x:Number = 0.0 , y:Number = 0.0 , z:Number = 0.0, w:Number = 0.0):void
		{
			_x	=	x ;
			_y	=	y ;
			_z	=	z ;
			_w	=	w ;
		}
		
		public function SetX(val:Number = 0.0):void
		{
			_x	=	val ;
		}
		public function SetY(val:Number = 0.0):void
		{
			_y	=	val ;
		}
		public function SetZ(val:Number = 0.0):void
		{
			_z	=	val ;
		}
		public function SetW(val:Number = 0.0):void
		{
			_w	=	val ;
		}
		
		public function Copy(vect:Vector4):void
		{
			this.SetXyzw(vect.X(), vect.Y(), vect.Z(), vect.W()) ;
		}
		
		public function Subtract(v1:Vector4,v2:Vector4):void
		{
			this._x	=	v1._x  - v2._x;	
			this._y	=	v1._y  - v2._y;	
			this._z	=	v1._z  - v2._z;	
			this._w	=	v1._w  - v2._w;	

		}

		public function Add(v1:Vector4,v2:Vector4):void
		{
			this._x	=	v1._x  + v2._x;	
			this._y	=	v1._y  + v2._y;	
			this._z	=	v1._z  + v2._z;	
			this._w	=	v1._w  + v2._w;	
			
		}
		
		public function Cross(src1:Vector4,src2:Vector4):void
		{
			this._x = ( src1._y * src2._z ) - ( src1._z * src2._y ) 
			this._y = ( src1._z * src2._x ) - ( src1._x * src2._z ) 
			this._z = ( src1._x * src2._y ) - ( src1._y * src2._x )
			
		}
		
		public function Length4():Number
		{
			return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w) ;
		}
		
		public function Length3():Number
		{
			return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z) ;
		}
		
		public function Length2():Number
		{
			return Math.sqrt(this._x * this._x + this._y * this._y) ; 
		}
		
		public function mag():Number
		{
			return this.Length4() ;
		}
		
		public function Normal2():Vector4
		{
			var v:Vector4	=	new Vector4(this._x, this._y, this._z, this._w) ;
			v._z = 0
			v._w = 0
			v.Normalise2()
			return v ;
		}
		
		public function Normal3():Vector4
		{
			var v:Vector4	=	new Vector4(this._x, this._y, this._z, this._w) ;
			v._w = 0
			v.Normalise3()
			return v ;
		}

		public function Normal4():Vector4
		{
			var v:Vector4	=	new Vector4(this._x, this._y, this._z, this._w) ;
			v.Normalise4()
			return v ;
		}

		
		public function Normalise2():void
		{
			var len:Number  = this.Length2() ;
			this.SetXyzw(this._x / len, this._y / len, this._z, this._w) ;
		}
		
		public function Normalise3():void
		{
			var len:Number  = this.Length3() ;
			this.SetXyzw(this._x / len, this._y / len, this._z / len, this._w) ;
		}
		
		public function Normalise4():void
		{
			var len:Number  = this.Length4() ;
			this.SetXyzw(this._x / len, this._y / len, this._z / len, this._w / len) ;
		}
		

		public function Dot2(v:Vector4):Number
		{
			return this._x * v._x + this._y * v._y ;
		}

		public function Dot3(v:Vector4):Number
		{
			return this._x * v._x + this._y * v._y + this._z * v._z ;
		}
		
		public function Dot4(v:Vector4):Number
		{
			return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w ;
		}

		// TODO
		public 	function Calculate2dLineIntersection( intersectionPoint:Vector4,  
													  p0:Vector4,  
													  p1:Vector4,  
													  q0:Vector4,  
													  q1:Vector4,  
													  infiniteLine:Boolean  = true):Object
		{

			return {}
		}
		
	}
}